/**
* 
* Copyright [2007] [Sunny Liu]
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/
package ${appConfig.outputPackageName}.xml;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

/**
 * @author LiuS
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public abstract class AbstractObjectXMLSerializer implements
		ObjectXMLSerializer {
	
	private static Logger log = LoggerFactory.getLogger(AbstractObjectXMLSerializer.class);
	
	
	/* (non-Javadoc)
	 * @see com.nyse.regtech.budget.xml.ObjectXMLSerializer#serialize(java.lang.Object, java.io.OutputStream)
	 */
	public void serialize(Object object, OutputStream out) throws IOException 
	{
		if(log.isDebugEnabled()) log.debug("Entering serialize(Object object, OutputStream out)");
		serialize(0, 200, "", object, out);		
		if(log.isDebugEnabled()) log.debug("Exiting serialize(Object object, OutputStream out)");


	}
	
	
	/* (non-Javadoc)
	 * @see com.nyse.regtech.budget.xml.ObjectXMLSerializer#serialize(int, int, java.lang.String, java.io.OutputStream)
	 */
	public void serialize(int action, int status, String message,
	OutputStream out) throws IOException 
	{
		if(log.isDebugEnabled()) log.debug("Entering serialize(int action, int status, String message, Object object, OutputStream out)");
		if(out==null)    throw new IllegalArgumentException("OutputStream can not be null.");		
		Document doc = null;
		try {
			doc = createResponseTemplateDocument(new Integer(action), status, message);			
			serializeDocument(doc, out);
		} catch (Exception e) {			
			log.error("Failed to Serialize.", e);
			throw new IOException("Serilization Exception.");
		}
		if(log.isDebugEnabled()) log.debug("Exiting serialize(int action, int status, String message, Object object, OutputStream out)");
		
	}
	
	
	protected static Document createResponseTemplateDocument(int status, String message) throws Exception
	{
		return createResponseTemplateDocument(null, status, message);
	}
	
	
	
	protected static Document createResponseTemplateDocument(Integer action, int status, String message) throws Exception
	{		
		 DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
         DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
         Document doc = docBuilder.newDocument(); 
         Element root = doc.createElement(XML_RESPONSE_ROOT);
         doc.appendChild(root); 
         Element header = doc.createElement(XML_RESPONSE_HEADER);
         root.appendChild(header);
        
         Element sta = doc.createElement(XML_RESPONSE_STATUS);
         header.appendChild(sta);        
         Text text = doc.createTextNode((new Integer(status)).toString());
       	 sta.appendChild(text);       	 
       	 if(action!=null){
	       	 Element act = doc.createElement(XML_RESPONSE_ACTION);
	         header.appendChild(act);        
	         text = doc.createTextNode(action.toString());
	         act.appendChild(text);
       	 }
       	 Element msg = doc.createElement(XML_RESPONSE_MESSAGE);
       	 header.appendChild(msg);
       if(message!=null){
	        text = doc.createTextNode(message);
	        msg.appendChild(text);
        }        
		return doc;
	}
	
	
	protected static void serializeDocument(Document doc, OutputStream out)
	{
		if(log.isDebugEnabled()) log.debug("Entering AbstractObjectXMLSerializer serialize()");
		try {        
            TransformerFactory transfac = TransformerFactory.newInstance();
            Transformer trans = transfac.newTransformer();
            trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            trans.setOutputProperty(OutputKeys.INDENT, "yes");    
            trans.setOutputProperty(OutputKeys.STANDALONE, "yes");  
            StreamResult result = new StreamResult(out);
            DOMSource source = new DOMSource(doc);
            trans.transform(source, result);           
            if(log.isDebugEnabled()) log.debug("Exiting AbstractObjectXMLSerializer serialize()");
       } catch (Exception e) {
        	throw new RuntimeException("Serialization Exception : " + e.toString());
        }
	}
	
	
	protected static String toXMLString(Document doc)
	{
		if(log.isDebugEnabled()) log.debug("Entering AbstractObjectXMLSerializer toXMLString()");
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		serializeDocument(doc, out);
		byte[] bytes = out.toByteArray();
		return new String(bytes);
	}
	
	
	
	
	
	
	
	
	
	
	/**
	 * 
	 */
	public AbstractObjectXMLSerializer() {
		super();
		// TODO Auto-generated constructor stub
	}

	

}
